package com.suxin.ratelimit;

import com.suxin.ratelimit.filters.RateLimiterWrapperFilter;
import com.suxin.ratelimit.properties.RateLimiterProperties;
import com.suxin.ratelimit.repository.InMemoryRateLimiter;
import com.suxin.ratelimit.repository.RateLimiter;
import com.suxin.ratelimit.repository.RedisRateLimiter;
import com.suxin.ratelimit.repository.springdata.JpaRateLimiter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;

/**
 * @author Tang
 * @classname RateLimiterAutoConfiguration
 * @description [  ]
 * @date 2021/7/15 20:21
 */
@EnableConfigurationProperties(RateLimiterProperties.class)
@ConditionalOnProperty(prefix = "gateway.ratelimit.enable",havingValue = "true",matchIfMissing = false)
@Configuration
public class RateLimiterAutoConfiguration {

    @ConditionalOnProperty(prefix = "gateway.ratelimit.repository",havingValue = "IN_MEMORY")
    @Bean
    public RateLimiter inMemoryRateLimiter() {
        return new InMemoryRateLimiter();
    }

    @ConditionalOnProperty(prefix = "gateway.ratelimit.repository",havingValue = "JPA")
    @Bean
    public RateLimiter jpaRateLimiter() {
        return new JpaRateLimiter();
    }

    @Bean("rateLimiterRedisTemplate")
    public RedisTemplate redisTemplate(final RedisConnectionFactory connectionFactory) {
        return new StringRedisTemplate(connectionFactory);
    }

    @ConditionalOnProperty(prefix = "gateway.ratelimit.repository",havingValue = "REDIS")
    @Bean
    public RateLimiter redisRateLimiter(RedisTemplate redisTemplate) {
        return new RedisRateLimiter(redisTemplate);
    }

    @Bean
    @ConditionalOnClass(value = RateLimiter.class)
    RateLimiterWrapperFilter rateLimiterWrapperFilter() {
        return new RateLimiterWrapperFilter();
    }

}